package com.lambkit.module.upms.encrypt;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import com.jfinal.core.Controller;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.StrKit;
import com.jfinal.render.Render;
import com.jfinal.render.RenderException;
import com.lambkit.Lambkit;
import com.lambkit.web.ResultKit;
import com.lambkit.common.util.StringUtils;

public class RSAKeyRender extends Render {

	protected static String captchaName = "_lambkit_upms_key";
	
	/**
	 * http://zh.wikipedia.org/zh/MIME
	 * 在wiki中查到: 尚未被接受为正式数据类型的subtype，可以使用x-开始的独立名称（例如application/x-gzip）
	 * 所以以下可能要改成 application/x-json
	 * 
	 * 通过使用firefox测试,struts2-json-plugin返回的是 application/json, 所以暂不改为 application/x-json
	 * 1: 官方的 MIME type为application/json, 见 http://en.wikipedia.org/wiki/MIME_type
	 * 2: IE 不支持 application/json, 在 ajax 上传文件完成后返回 json时 IE 提示下载文件
	 */
	protected static final String contentType = "application/json; charset=" + getEncoding();
	protected static final String contentTypeForIE = "text/html; charset=" + getEncoding();
	protected boolean forIE = false;
	
	public RSAKeyRender forIE() {
		forIE = true;
		return this;
	}
	
	@Override
	public void render() {
		// TODO Auto-generated method stub
		RSAKey key = new RSAKey();
		String uuid = StringUtils.uuid();
		
		//cache
		Lambkit.getCache().put(captchaName, uuid, key, 60 * 10);//10分钟
		
		//cookie
		Cookie cookie = new Cookie(captchaName, uuid);
		cookie.setMaxAge(-1);
		cookie.setPath("/");
		response.addCookie(cookie);
		response.setHeader("Pragma","no-cache");
		response.setHeader("Cache-Control","no-cache");
		response.setDateHeader("Expires", 0);
		response.setContentType("image/jpeg");
		
		//json
		String jsonText = JsonKit.toJson(ResultKit.json(1, uuid, key.getPublicKey()));
		
		PrintWriter writer = null;
		try {
			// response.setHeader("Cache-Control", "no-cache");
			response.setContentType(forIE ? contentTypeForIE : contentType);
			writer = response.getWriter();
			writer.write(jsonText);
			// writer.flush();
		} catch (IOException e) {
			throw new RenderException(e);
		}
	}
	
	/**
	 * 解密用户输入的密码
	 * @param controller 控制器
	 * @param userInputString 用户输入的密码
	 * @return 返回密码明文
	 */
	public static String getPassword(Controller controller, String userInputString) {
		userInputString = userInputString.replaceAll("%2B","+");
		String cacheKey = controller.getCookie(captchaName);
		if(StrKit.isBlank(cacheKey)){
			cacheKey = controller.get("captchaName");
			if(StrKit.isBlank(cacheKey)){
				return userInputString;
			}
		}
		return getPassword(cacheKey, userInputString);
	}
	
	/**
	 * 解密用户输入的密码
	 * @param request 控制器
	 * @param userInputString 用户输入的密码
	 * @return 返回密码明文
	 */
	public static String getPassword(HttpServletRequest request, String userInputString) {
		String cacheKey = getCookie(request, captchaName, null);
		if(StrKit.isBlank(cacheKey)){
			return userInputString;
		}
		return getPassword(cacheKey, userInputString);
	}
	
	/**
	 * 解密用户输入的密码
	 * @param cacheKey 验证码 key，在不支持 cookie 的情况下可通过传参给服务端
	 * @param userInputString 用户输入的字符串
	 * @return 验证通过返回 true, 否则返回 false
	 */
	public static String getPassword(String cacheKey, String userInputString) {
		RSAKey rsakey = Lambkit.getCache().get(captchaName, cacheKey);
		if (rsakey != null) {
			return rsakey.decrypt(userInputString);
		}
		return userInputString;
	}
	
	/**
	 * Get cookie value by cookie name.
	 */
	public static String getCookie(HttpServletRequest request, String name, String defaultValue) {
		Cookie cookie = getCookieObject(request, name);
		return cookie != null ? cookie.getValue() : defaultValue;
	}
	
	public static Cookie getCookieObject(HttpServletRequest request, String name) {
		Cookie[] cookies = request.getCookies();
		if (cookies != null)
			for (Cookie cookie : cookies)
				if (cookie.getName().equals(name))
					return cookie;
		return null;
	}

}
